#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BORRA_BUFFER    while(getchar()!= '\n');
#define MAX_MSG_LEN	200
#define EXTR_FREQ	4
#define HIGH_LIM	3
#define LOW_LIM		8

int getPos(char letra, char * arr);
void count (char letra, int * arr, int i, char * msg);
int getLine (char * line, int linelen, FILE * stream);
int isPossible (char * msg);

/* Reemplace la 'Ñ' por un '.' por representacion */
int
main (void)
{
	int i = 0, j, max = 0;
	char * freq = "EAOSRNIDLCTUMPBGVYQHFZJXWK.";
//	char * msg_enc = "VKXYKBKXGKSGWAKQQGYIUYGYWAKXKGQRKSZKJKYKKYIUSYKMA.X";
	char msg_enc[MAX_MSG_LEN];
	char * alf = "ABCDEFGHIJKLMN.OPQRSTUVWXYZ";
	int key;
	int * arr;
	char * des;
	int * pos;
	int flag = 1, alf_len, msg_len;
	
	printf("Ingrese el texto encriptado con metodo Cesar: ");
	getLine (msg_enc, MAX_MSG_LEN, stdin);
	
	alf_len = strlen(alf);
	msg_len = strlen(msg_enc);
	
	arr = (int *) calloc (alf_len, sizeof(int));
	
	des = (char *) calloc ( msg_len, sizeof(char));
	
	pos = (int *) calloc (msg_len , sizeof(int));
	
	
	for (i = 0; i < msg_len; i++)
	{
		flag = 1;
		for (j = 0; (j < alf_len && flag); j++)
		{
			if (msg_enc[i] == alf[j])
			{
				pos[i] = j;
				flag = 0;
			}
		}
	}
	
	for(i = 0; i < alf_len; i++)
	{
		count(alf[i], arr, i, msg_enc);
	}
	
	printf("\n%s\n", alf);
	
	for (i = 0; i < alf_len; i++)
	{
		printf("%d", arr[i]);
	}
	printf("\n");
	
	for (j = 0; j < alf_len; j++)
	{
		if (arr[max] < arr[j])
			max = j;
	}
	
	if (alf[max] == freq[0] || alf[max] == freq[1] || alf[max] == freq[2])
		printf ("\nPOSIBLE TRANSPOSICION!!\n\n");
	
	for (i = 0; i < 12; i++)
	{
		if ((key = max - getPos (freq[i], alf)) < 0)
			key += alf_len;
		
		int neg;
		for (j = 0; j < msg_len; j++)
		{
			if ((neg = (pos[j] - key)) < 0)
				des[j] = alf[alf_len + neg];
			else
				des[j] = alf[pos[j] - key];
		}
		if (isPossible (des))
			printf ("MESSAGE:\n    %s\n", des);
	}
	
	
	return 0;
}

void
count (char letra, int * arr, int i, char * msg)
{
	int tot;
	int cant = 0;
	int j = 0;
	
	tot = strlen(msg);
	while (j < tot)
	{
		if (msg[j++] == letra)
			cant++;
	}
	arr[i] = cant;
}

int getPos(char letra, char * arr)
{
	int cant;
	int i;
	
	cant = strlen(arr);
	for(i = 0; i < cant; i++)
	{
		if (letra == arr[i])
			return i;
	}
	return -1;
}

int
getLine (char * line, int linelen, FILE * stream)
{
    int i=0, c;
    for (i=0;i<linelen;i++)
        line[i] = 0;
    i=0;
    while(i<linelen){
        c=fgetc(stream);
        if(c==EOF)
                return -1;

        if(c=='\n')
                return 1;

        line[i]=c;
        i++;
    }

    if (i >= linelen)
        {
            BORRA_BUFFER;
        return 0;
        }
    return 0;
}

int isPossible (char * msg)
{
	char * freq = "EAOSRNIDLCTUMPBGVYQHFZJXWK.";
	int msg_len, alf_len;
	int * reps;
	float * perc;
	int i;
	
	alf_len = strlen(freq);
	msg_len = strlen(msg);
	
	if ((reps = (int *) malloc(alf_len * sizeof(int))) == NULL)
	{
		printf("Malloc Error\n");
		exit (1);
	}
	if ((perc = (float *) malloc(alf_len * sizeof(float))) == NULL)
	{
		printf("Malloc Error\n");
		exit (1);
	}
	
	for (i = 0; i < alf_len; i++)
	{
		count (freq[i], reps, i, msg);
		perc[i] = (float)((int)(((float)(reps[i] * 100) / msg_len) * 100)) / 100;
	}
	
	for (i = 0; i < EXTR_FREQ; i++)
	{
		if (perc[i] < HIGH_LIM)
		{
			free(reps);
			free(perc);
			return 0;
		}
	}
	
	for (i = alf_len - 1; i > ((alf_len - EXTR_FREQ) - 1); i--)
	{
		if (perc[i] > LOW_LIM)
		{
			free(reps);
			free(perc);
			return 0;
		}
	}
	free(reps);
	free(perc);
	return 1;
}